import 'dart:async';
import 'dart:math';

import 'package:cc_sdk/models/comment_model.dart';
import 'package:cc_sdk/models/comment_statistics.dart';
import 'package:cc_sdk/models/member_info.dart';
import 'package:cc_sdk/models/pager_result.dart';
import 'package:cc_sdk/services/comment_service.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' show DateFormat;
import 'package:flutter_easyrefresh/easy_refresh.dart';

typedef OnStatisticsEvent(CommentStatistics statistics);
typedef Future<MemberInfo> GetMemberInfo(int memberId);

class CommentListController {
  final OnStatisticsEvent onStatisticsEvent;
  final GetMemberInfo getMemberInfo;
  final Function onLogin;

  CommentListController(
      {this.onStatisticsEvent, this.getMemberInfo, this.onLogin});

  _CommentListWidgetState _state;

  set widgetState(_CommentListWidgetState v) {
    _state = v;
    _state.pagerController = _pagerController;
  }

  StreamController<PagerResult<CommentModel>> _pagerController =
  StreamController.broadcast();

  void insert(CommentModel model) {
    _state?.insert(model);
  }

  Stream<PagerResult<CommentModel>> get pagerStream => _pagerController.stream;

  void dispose() {
    _pagerController.close();
  }

  void goTop() {
    _state.goTop();
  }

  void onStatistics(CommentStatistics statistics) {
    if (onStatisticsEvent != null) {
      onStatisticsEvent(statistics);
    }
  }
}

class CommentListWidget extends StatefulWidget {
  final int parentId;
  final String outId;
  final int memberId;
  final CommentListController controller;
  _CommentListWidgetState widgetState;
  final Widget header;

  CommentListWidget({Key key,
    this.parentId,
    this.outId,
    this.memberId,
    this.controller,
    this.header})
      : super(key: key);

  @override
  _CommentListWidgetState createState() {
    widgetState = new _CommentListWidgetState(parentId, outId);
    controller?.widgetState = widgetState;
    return widgetState;
  }
}

class _CommentListWidgetState extends State<CommentListWidget>
    with AutomaticKeepAliveClientMixin {
  final int parentId;
  final String outId;
  StreamController<PagerResult<CommentModel>> _pagerController;
  List<MemberInfo> memberList = [];

  set pagerController(StreamController<PagerResult<CommentModel>> v) {
    _pagerController = v;
  }

  _CommentListWidgetState(this.parentId, this.outId);

  int _pageIndex = 1;

  EasyRefreshController _refreshController;
  ScrollController _scrollController;
  List<CommentModel> _list = [];

  Stream<PagerResult<CommentModel>> get pagerStream => _pagerController.stream;

  initState() {
    super.initState();
    _refreshController = EasyRefreshController();
    _scrollController = ScrollController();
    _load();
  }

  void insert(CommentModel model) {
    _list.insert(0, model);
    _scrollController?.position?.animateTo(0,
        duration: Duration(milliseconds: 100), curve: Curves.easeIn);
    //  setState(() {});
  }

  Future _load() async {
    try {
      var result = await CommentService.internal()
          .list(outId, parentId, _pageIndex, widget.memberId);
//      _list.removeWhere((org) {
//        return pagerResult.list.any((nw) => nw.commentId == org.commentId);
//      });
      var pagerResult = result.pager;
      widget.controller.onStatistics(result.statistics);
      _list.addAll(pagerResult.list);
      if (_pageIndex == 1) {
        _refreshController.finishRefresh(
            success: true, noMore: pagerResult.pageCount <= _pageIndex);
      } else {
        _refreshController.finishLoad(
            success: true, noMore: pagerResult.pageCount <= _pageIndex);
      }
      _pageIndex++;
      Future(() {
        _pagerController?.add(pagerResult);
      });
    } catch (ex) {
      if (_pageIndex == 1) {
        _refreshController.finishRefresh(success: false, noMore: true);
      } else {
        _refreshController.finishLoad(success: false, noMore: true);
      }
      print(ex);
    }
    if (mounted) setState(() {});
  }

  Future _onRefresh() async {
    _list.clear();
    await _load();
  }

  Future _onLoading() async {
    await _load();
  }

  @override
  Widget build(BuildContext context) {
    return _buildList(context);
  }

  Widget _buildContent(BuildContext context, CommentModel model) {
    model.context = model.context;
    var style =
    TextStyle(color: Color(int.parse("ff222222", radix: 16)), height: 1.2);
    var maxLines = 4;
    var textSpan = TextSpan(text: model.context, style: style);

    return RichText(
      text: textSpan,
      maxLines: maxLines,
      overflow: TextOverflow.ellipsis,
    );
  }

  Widget _buildCreateTime(BuildContext context, CommentModel model) {
    var createTime = DateTime.parse(model.createTime);
    var duration = DateTime.now().difference(createTime);
    var text = "";
    if (duration.inDays == 0) {
      if (duration.inHours > 0) {
        text = "${duration.inHours}小时前";
      } else if (duration.inMinutes > 0) {
        text = "${duration.inMinutes}分钟前";
      } else {
        text = "刚刚";
      }
    } else {
      text = DateFormat('MM-dd HH:mm:ss').format(
        createTime,
      );
    }
    return Container(
      padding: EdgeInsets.only(top: 10),
      child: Text(
        text,
        style: TextStyle(color: Colors.grey),
      ),
    );
  }

  Future getMember(int memberId) async {
    if (widget.controller.getMemberInfo != null) {
      var info = await widget.controller.getMemberInfo(memberId);
      if (info != null) {
        memberList.add(info);
        setState(() {});
      }
    }
  }

  void like(CommentModel model) {
    if (widget.memberId > 0) {
      var modelOutId = "_inner_comment_${model.commentId}";
      if (model.myLike) {
        model.likeCount--;
        CommentService.internal().unlike(modelOutId, widget.memberId);
      } else {
        CommentService.internal().like(modelOutId, widget.memberId);
        model.likeCount++;
      }
      model.myLike = !model.myLike;
      setState(() {});
    } else {
      widget.controller.onLogin();
    }
  }

  Widget _buildLike(BuildContext context, CommentModel model) {
    var normalColor = Color(0xFF6c6c6c);
    var hitColor = Color(0xFFcf0909);
    String text = "";

    if (model.likeCount > 0) {
      if (model.likeCount >= 10000) {
        text = "${model.likeCount ~/ 10000}万+";
      } else if (model.likeCount >= 1000) {
        text = "${model.likeCount ~/ 1000}千+";
      } else {
        text = model.likeCount.toString();
      }
    }

    var color = model.myLike ? hitColor : normalColor;
    return GestureDetector(
      onTap: () {
        like(model);
      },
      child: Container(
        child: Row(
          children: <Widget>[
            Icon(
              Icons.thumb_up,
              color: color,
            ),
            Container(
              padding: EdgeInsets.only(left: 2),
              child: Text(
                text,
                style: TextStyle(
                  color: color,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildAvatar(BuildContext context, String avaterUrl) {
    return Container(
      padding: EdgeInsets.only(top: 10, right: 5),
      child: ClipOval(
        child: avaterUrl == null
            ? Icon(
          Icons.account_circle,
          size: 45,
          color: Color(0xffc0c0c0),
        )
            : Image.network(
          "$avaterUrl?width=80&height=80&mode=crop",
          width: 40,
          height: 40,
        ),
      ),
    );
  }

  Widget _buildItem(BuildContext context, CommentModel model) {
    var infos = memberList.where((s) => s.memberId == model.memberId);
    String nickName = "正在加载...";
    String avaterUrl;
    if (infos.length > 0) {
      nickName = infos.first.nickName;
      avaterUrl = infos.first.avaterUrl;
    } else {
      getMember(model.memberId);
    }
    var screenSize = MediaQuery
        .of(context)
        .size;
    return Container(
      padding: EdgeInsets.all(3),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          _buildAvatar(context, avaterUrl),
          Container(
            padding: EdgeInsets.only(bottom: 10),
            decoration: BoxDecoration(
              border: Border(
                bottom:
                BorderSide(color: Color(int.parse("ffe8e8e8", radix: 16))),
              ),
            ),
            width: screenSize.width - 60,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Container(
                      child: Text(
                        nickName,
                        style: TextStyle(
                          color: Color(
                            int.parse("FF406599", radix: 16),
                          ),
                          fontWeight: FontWeight.w600,
                          fontSize: 16,
                        ),
                      ),
                      padding: EdgeInsets.only(top: 10, bottom: 10),
                    ),
                    _buildLike(context, model),
                  ],
                ),
                _buildContent(context, model),
                _buildCreateTime(context, model),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildList(BuildContext context) {
    return EasyRefresh(
      enableControlFinishRefresh: false,
      enableControlFinishLoad: true,
      controller: _refreshController,
     // onRefresh: _onRefresh,
      onLoad: _onLoading,
      child: ListView.builder(
        controller: _scrollController,
        itemBuilder: (c, i) {
          int index = i;
          if (index == 0) {
            if (widget.header != null) {
              return widget.header;
            }
          }
          if (widget.header != null) {
            index--;
          }
          var model = _list[index];
          return GestureDetector(
            child: _buildItem(context, model),
            onTap: () {},
          );
        },
        itemCount: widget.header != null ? _list.length + 1 : _list.length,
      ),
    );
  }

  void dispose() {
    _refreshController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  bool get wantKeepAlive => true;

  void goTop() {
    _scrollController?.position?.animateTo(0,
        duration: Duration(milliseconds: 100), curve: Curves.easeIn);
  }
}
